﻿using Autofac;
using AutoMapper;
using gt.dotnetcore.webapi.extensions;
using gt.dotnetcore.webapi.extensions.ApiException;
using gt.dotnetcore.webapi.extensions.ApiLogging;
using gt.UserInfo.ApplicationServices;
using gt.UserInfo.ApplicationServices.Impl;
using gt.UserInfo.DomainModels.Abstractions;
using gt.UserInfo.DomainModels.Respository;
using gt.UserInfo.DomainServices;
using gt.UserInfo.Intrastructures.EF;
using gt.UserInfo.Intrastructures.Mapper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Reflection;

namespace gt.UserInfo
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureContainer(ContainerBuilder builder)
        {
            //TODO 如何支持多个数据库链接DbContext？
            //具体的 Repository，可以依赖具体的 DbContext
            builder.RegisterType<MyDataContext>().As<DbContext>().InstancePerLifetimeScope();

            #region repository

            builder.RegisterType<UserRepository>().As<IUserRepository>().InstancePerLifetimeScope();

            #endregion

            #region domainService

            builder.RegisterType<UserDomainService>().As<IUserDomainService>().InstancePerLifetimeScope();

            #endregion

            #region appService

            builder.RegisterType<UserAppService>().As<IUserAppService>().InstancePerLifetimeScope();

            #endregion

            #region middlerware

            //builder.RegisterType<GlobalExceptionMiddleware>().AsSelf().SingleInstance();
            //builder.RegisterType<GlobalApiLoggingMiddleware>().AsSelf().SingleInstance();

            #endregion
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            services.AddApiVersioning(options =>
            {
                options.ReportApiVersions = true;
                options.AssumeDefaultVersionWhenUnspecified = true;
                options.DefaultApiVersion = new ApiVersion(1, 0);
            });

            services.AddAutoMapper(Assembly.GetAssembly(typeof(MapperProfiles)));
            services.AddDbContext<MyDataContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddHttpContextAccessor();
            //services.AddAuthorization(options => {
            //    options.AddPolicy("headclaims", builder => {
            //        builder.RequireScope("");
            //    });
            //});
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseRouting();

            app.UseGlobalException();
            app.UseGlobalApiLogging();

            //app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

        /*  .net core 2.x 的写法
        private void ConfigureInjections(IServiceCollection services)
        {
            //TODO 如何支持多个数据库链接DbContext？
            //具体的 Repository，可以依赖具体的 DbContext
            services.AddScoped<DbContext, MyDataContext>();

            #region repository

            services.AddScoped<IUserRepository, UserRepository>();

            #endregion

            #region domainService

            services.AddScoped<IUserDomainService, UserDomainService>();

            #endregion

            #region appService

            services.AddScoped<IUserAppService, UserAppService>();

            #endregion

            #region middlerware

            //services.AddScoped<GlobalExceptionMiddleware>();
            //services.AddScoped<GlobalApiLoggingMiddleware>();

            #endregion
        }
        public IContainer ApplicationContainer { get; private set; }
        private IServiceProvider ConfigureInjectionsWithAutofac(IServiceCollection services)
        {
            var builder = new ContainerBuilder();
            //very import
            //正常返回IServiceProvider 并不能替代原IServicePrivder。还需要自定义ServiceScopeFactory保证RequestServices返回的也是你自定义的ServiceProvider。
            //详细见https://www.cnblogs.com/artech/p/3rd-party-di-integration.html
            //此处autofac做了特殊处理
            builder.Populate(services);

            //TODO 如何支持多个数据库链接DbContext？
            //具体的 Repository，可以依赖具体的 DbContext
            builder.RegisterType<MyDataContext>().As<DbContext>().InstancePerLifetimeScope();

            #region repository

            builder.RegisterType<UserRepository>().As<IUserRepository>().InstancePerLifetimeScope();

            #endregion

            #region domainService

            builder.RegisterType<UserDomainService>().As<IUserDomainService>().InstancePerLifetimeScope();

            #endregion

            #region appService

            builder.RegisterType<UserAppService>().As<IUserAppService>().InstancePerLifetimeScope();

            #endregion

            #region middlerware

            builder.RegisterType<GlobalExceptionMiddleware>().AsSelf().InstancePerLifetimeScope();
            builder.RegisterType<GlobalApiLoggingMiddleware>().AsSelf().InstancePerLifetimeScope();

            #endregion

            ApplicationContainer = builder.Build();

            return new AutofacServiceProvider(ApplicationContainer);
        }
        */
    }
}
